package net.zoneland.zoneapp.view;

import net.zoneland.zoneapp.R;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.HorizontalScrollView;
import android.widget.LinearLayout;

import com.nineoldandroids.view.ViewHelper;

/**
 * 仿qq5.0 侧滑菜单
 * 
 * @author FancyLou
 * @date 2015年4月21日 下午9:44:30
 *
 */
public class SlidingView extends HorizontalScrollView {

	private LinearLayout mWrapper;
	private ViewGroup mMenu;
	private ViewGroup mContent;

	private int mScreenWidth;// 屏幕宽度
	// 单位dp
	private int mMenuRightPadding = 50;

	private int mMenuWidth;

	private boolean onceOnMeasure = false;

	/**
	 * 菜单是否开启
	 */
	private boolean isOpen = false;

	/**
	 * 用于OnTouchEvent判断是点击还是其他手势
	 */
	private int oldEvent = -11;

	// 未使用自定义属性的时候使用
	public SlidingView(Context context, AttributeSet attrs) {
		this(context, attrs, 0);

	}

	public SlidingView(Context context) {
		this(context, null);
	}

	// 自定义属性时候 会使用这个构造方法
	public SlidingView(Context context, AttributeSet attrs, int defStyleAttr) {
		super(context, attrs, defStyleAttr);
		// 获取我们定义的属性
		TypedArray array = context.getTheme().obtainStyledAttributes(attrs,
				R.styleable.SlidingView, defStyleAttr, 0);
		int n = array.getIndexCount();
		for (int i = 0; i < n; i++) {
			int attr = array.getIndex(i);
			switch (attr) {
			case R.styleable.SlidingView_rightPadding:
				mMenuRightPadding = array.getDimensionPixelOffset(attr,
						(int) TypedValue.applyDimension(
								TypedValue.COMPLEX_UNIT_DIP, 50, context
										.getResources().getDisplayMetrics()));
				break;
			}
		}

		array.recycle();

		WindowManager wm = (WindowManager) context
				.getSystemService(Context.WINDOW_SERVICE);
		DisplayMetrics dm = new DisplayMetrics();
		wm.getDefaultDisplay().getMetrics(dm);
		mScreenWidth = dm.widthPixels;

		// Typedvalue 会把50dp转化为像素值 把dp转化为px
		// mMenuRightPadding = (int)
		// TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 50,
		// context.getResources().getDisplayMetrics());
	}

	// 决定内部View的宽和高，以及自己的宽和高
	// 设置子View的宽和高 自己的宽和高
	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		if (!onceOnMeasure) {
			mWrapper = (LinearLayout) getChildAt(0);
			mMenu = (ViewGroup) mWrapper.getChildAt(0);
			mContent = (ViewGroup) mWrapper.getChildAt(1);
			mMenuWidth = mMenu.getLayoutParams().width = mScreenWidth
					- mMenuRightPadding;
			mContent.getLayoutParams().width = mScreenWidth;
			onceOnMeasure = true;
		}
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
	}

	// 决定子View的放置的位置
	// 默认情况menu在左边所以会显示出来，这里设置偏移量将menu默认隐藏
	@Override
	protected void onLayout(boolean changed, int l, int t, int r, int b) {

		super.onLayout(changed, l, t, r, b);
		if (changed) {
			this.scrollTo(mMenuWidth, 0);
		}

	}

	@SuppressLint("ClickableViewAccessibility")
	@Override
	public boolean onTouchEvent(MotionEvent ev) {
		int action = ev.getAction();
		// 判断是否点击事件 并且是点击在内容区域中的 就关闭菜单
		if (oldEvent == MotionEvent.ACTION_DOWN
				&& action == MotionEvent.ACTION_UP) {
			if (isOpen) {
				if (inRangeOfView(mContent, ev)) {
					this.smoothScrollTo(mMenuWidth, 0);// 关闭菜单
					isOpen = false;
					oldEvent = action;
					return true;
				}
			}
		}
		oldEvent = action;
		switch (action) {
		case MotionEvent.ACTION_UP:// 手指抬起时候的事件
			// 隐藏在左边的宽度
			int scrollX = getScrollX();
			if (scrollX >= (mMenuWidth / 2)) {
				this.smoothScrollTo(mMenuWidth, 0);// 动画效果
				isOpen = false;
			} else {
				this.smoothScrollTo(0, 0);
				isOpen = true;
			}
			return true;
		}

		return super.onTouchEvent(ev);
	}

	private boolean inRangeOfView(View view, MotionEvent ev) {
		int[] location = new int[2];
		view.getLocationOnScreen(location);
		int x = location[0];
		int y = location[1];
		if (ev.getX() < x || ev.getX() > (x + view.getWidth()) || ev.getY() < y
				|| ev.getY() > (y + view.getHeight())) {
			return false;
		}
		return true;
	}

	public void openMenu() {
		if (isOpen) {
			return;
		} else {
			this.smoothScrollTo(0, 0);
			isOpen = true;
		}

	}

	public void closeMenu() {
		if (!isOpen) {
			return;
		} else {
			this.smoothScrollTo(mMenuWidth, 0);
			isOpen = false;
		}

	}

	/**
	 * 切换菜单
	 */
	public void toggleMenu() {
		if (isOpen) {
			closeMenu();
		} else {
			openMenu();
		}
	}

	/**
	 * 滚动发生时
	 * 
	 * @param l
	 * @param t
	 * @param oldl
	 * @param oldt
	 */
	@Override
	protected void onScrollChanged(int l, int t, int oldl, int oldt) {
		super.onScrollChanged(l, t, oldl, oldt);
		// 调用属性动画，设置TranlationX
		// l是scrollx的值
		float scale = l * 1.0f / mMenuWidth; // 1~0

		// ViewHelper.setTranslationX(mMenu, mMenuWidth * scale);

		/**
		 * 1： 内容区域1.0~0.8的缩放效果，scale :1.0~0.0 0.8+0.2*scale 2：菜单的偏移量需要修改
		 * 3：菜单显示的时候有缩放和透明度的变化，缩放0.8~1.0 1.0-scale*0.2 透明度 0.6~1.0
		 * 0.6+0.4(1-scale)
		 */
		float rightScale = 0.8f + 0.2f * scale;
		float leftScale = 1.0f - scale * 0.3f;
		float leftAlpha = 0.2f + 0.8f * (1 - scale);
		// 调用属性动画，设置TranslateX
		ViewHelper.setTranslationX(mMenu, mMenuWidth * scale * 0.8f);
		ViewHelper.setScaleX(mMenu, leftScale);
		ViewHelper.setScaleY(mMenu, leftScale);
		ViewHelper.setAlpha(mMenu, leftAlpha);

		// 设置缩放的中心点 到左边 解决偏移量的问题
		ViewHelper.setPivotX(mContent, 0);
		ViewHelper.setPivotY(mContent, mContent.getHeight() / 2);
		ViewHelper.setScaleX(mContent, rightScale);
		ViewHelper.setScaleY(mContent, rightScale);

	}
}
